package com.yskj.dngame.kotiledemo

import com.yskj.dngame.kotiledemo.view.DataView

/**
 *kotlin学习笔记 基础篇
 * ps(由于觉得word文档写来不好看 ,所以就使用kt文件 ,使用中文命名试试  23333
 * 主要嘛是方便与练习了,复制代码过来 这里只记录部分写法 ,有一部分写法在Demo 中 ,可参考借鉴)
 *
 * 附一份官方的中文参考文档,
 * 这里的只是作为我自己的理解而写的笔记
 *
 * Created by SYZ
on 2017/8/30.
 */
class Kotlin学习笔记 {


    /**
     * 1.基础符号:
     * 万能的  :
     * :  在kotlin 中 实例化的时候 用此符号,可以做为继承的写法
     * :  可以用于继承,也可以用于实现接口方法   继承在对应的类名后面加上()  ,实现方法则不加
     * 2.?  判断是与否 boolean
     * 3.=  等于
     * ?可为空 !!非空
     * String 后面加问号 ,意思就是可以为空   不加问号 ,就是不能为空的意思
     *
     * val  和var  都是变量的意思,但实际含义是不一样的
     *      var  是一个可变变量，这是一个可以通过重新分配来更改为另一个值的变量。这种声明变量的方式和Java中声明变量的方式一样。
     *      val  是一个只读变量，这种声明变量的方式相当于java中的final变量。一个val创建的时候必须初始化，因为以后不能被改变。
     *
     *       主要区别:
     *       var 的变量在初始化后,可以改变值  ,
     *       而val在初始化后,就不能贝改变
     */
    //Java 写法:
    String name = null
    public class MainActivity extends Activity

    //  Kotlin 写法:
    var name: String? = null

    class MainActivity : Activity

    /**
     * 4.fun 是一个方法的意思,也可以是一个方法,带有返回参数 例:
     */
    // 调用方法:
    fun setData() {
    }

    //  有返回参数的方法:
    fun getData(): String {
    }


    /**
     * 5.MutableList 是一种泛型的List  例:
     */
    //Java写法
    List<Bean> listBean = new ArrrayList<>();

    //Kotlin中:
    // 如果用List写

    val listBean: List<Bean> = new ArrayList < > ();

    /**
     * 如果我们这里这个listBean 需要添加单个数据 ,是无法使用.add  也提示没有这个方法
     * 这个时候 就需要把我们的LIst 替换为 MutableList
     * 注:
     * 这时候就和平时我们是的list 是一样的用法了  MutableList 是继承list 的,如果在其他方法或者Adapter里面使用List<Bean>  也是能正常获取
     * 到值的,一样能读取数据,只是继承了List后 只能使用get方法了 ,不能使用其他的add.set.remove这几个方法
     */
    val mListBean: MutableList<Bean> = new ArrayList < > ();


    /**
     * 6.接口 及实现方法 ,这里和正常的接口类差不多
     */
    //接口类
    interface DataView {

        fun setItemPosition(postion: Int)

    }

    //实现接口 的两种方式

    //1.在顶部class位置实现 ,使用this初始化
    class MainActivity : DataView {
        .......
        .......

        override fun setItemPosition(position: Int) {
            LogUtil.i("点击了下标:" + position)
        }
    }

    //2.在代码中实现方法 ,类似于点击事件的单个new
    dataAdapter.setOnItem(
    object : DataView {
        override fun setItemPosition(position: Int) {
            LogUtil.i("点击了下标:" + position)
        }
    })


    /**
     * 7.as 关键字
     * 类似Java 中 String 强转为 int 类型
     * 用于局部重命名，以解决冲突
     * 如果出现名字冲突，可以使用 as 关键字在本地重命名冲突项来消歧义：
     *
     * 还是没搞懂..................................................................................****************************************
     */
    //例   :
    var datas: String = "1314.11561"

    //这里 我们的datas 是继承了String 字符串类型 ,如果我们要继续使用变量datas  但是不使用字符串类型了 ,希望转换为Int 类型
    //当转型不成功的时候，它会返回 null
    datas as? Double


    /**
     * 8. is 类型判断符
     * 检查某个实例是否是某个类型，如果判断出属于某个类型，那么判断后的分支中可以直接可当该类型使用
     * 如果一个不可变的局部变量或属性已经
     * 判断出为某类型，那么检测后的分支中可以直接当作该类型使用，无需显式转换：
     */
    fun setDatas(nums: Any) {
        //这里 这个 nums 是一个int 类型的
        //判断nums 是否为自己需要的类型
        if (nums is String) {//如果为字符串类型的时候

        } else if (nums is Int) {//为Int 类型时

        }
    }


    /**
     * 9 . companion object{ ..... }
     * 自己写的工具,希望直接成为静态 ,可以直接被使用的时候
     * 比如 Log.d()  类似这样的Java 写法
     *
     */

    companion object {
        fun setData(data: String) {
            ........
        }

        fun getData() {
            ........
        }
    }

    /**
     * 10. for循环
     *
     * item 为 单个java 中的i
     *
     */

    //第一种 写法
    val items = listOf("apple", "banana", "kiwi")
    for (item in items)
    {
        println(item)
    }

    //第二种写法
    val items = listOf("apple", "banana", "kiwi")
    for(item in nameArray.indices)
    {

    }


    /**
     * 11.数组
     */
    //设置数组 数据
    val hexDigits = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8',
            '9', 'A', 'B', 'C', 'D', 'E', 'F')
    //设置数组的长度
    var str = arrayOfNulls<Int>(7)


    /**
     * 12.constructor
     * 如果类有一个主构造函数，每个次构造函数需要委托给主构造函数  例如继承某个view 的时候
     * 里面包含了多个初始化的方法
     */
    class DatasLayout : LinearLayout {
        constructor(context: Context) : this(context, null)
        constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
        constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
            ......  //可以写上自己要初始化后需要操作的方法或者其他的
        }

    }


    /**
     * 13.  !!   ?.let{..}
     * 判断非空
     * 一般在判断一个字符串是否为空时,有好几种写法 ,这里写上kotlin 中的几种写法
     */
    fun setNames(names: String) {

        //1.这是我们在Java Android  中常见的一种判断方式
        if (names != null) {
            .......
        }

        //2.!!  非,不为空
        Log.d(names!!)

        // ?.let{..}  let  形式 ,判断如果不为空时,就执行大括号里面方法
        names?.let { .... }

    }


    /**
     * 14 when
     * 使用when语句实现Java中switch语句，和if else if 语句的效果
     * when会对所有的分支进行检查直到有一个条件满足。when 可以用做表达式或声明
     * 。如果用作表达式的话，那么满足条件的分支就是总表达式。如果用做声明，那么分支的值会被忽略。
     * (像 if 表达式一样，每个分支是一个语句块，而且它的值就是最后一个表达式的值)
     */

    //1. when表达式有参数：实现switch()语句效果
    fun setDatas(num;Int)
    {
        when (num) {
            1 -> LogUtil.d("点击了Item" + nums)

            2 -> LogUtil.d("点击了Item ****2****")
        }
    }

    //2.when表达式无参数： 实现if -else if-else语句效果
    fun hasPrefix(x: Any) = when (x) {
        is String -> x.startsWith("prefix")
        else -> false
    }


    /**
     * 15.try 异常
     * try、catch、finally三个语句块均不能单独使用，
     * 三者可以组成 try…catch…finally、try…catch、try…finally三种结构，catch语句可以有一个或多个，finally语句最多一个
     *
     * try {
     * // 某些代码
     * }
     * catch (e: SomeException) {
     * // 异常处理
     * }
     * finally {
     * // 可选的 finally 代码段
     * }
     *
     * finally语句块：紧跟catch语句后的语句块，这个语句块总是会在方法返回前执行，
     * 而不管是否try语句块是否发生异常。并且这个语句块总是在方法返回前执行。
     * 目的是给程序一个补救的机会。这样做也体现了Java语言的健壮性。
     *
     */


    /**
     * 16. data
     * 在Java 或者安卓中 ,接收到的 json 数据 ,很多人都一种习惯 ,写一个实体的Bean  类
     * 在kotlin 种 只需要在类名 后面加上自己的需要传递的参数即可
     * 编译器会为数据类(data class)自动生成以下函数:
     * equals()/hashCode()
     * toString() 默认输出"User(name=John, age=42)"
     * componentN() 按声明顺序对应于所有属性
     * copy()
     */

    //1.在class 类后面 添加构造参数的写法
    data class DataBean(var name: String, var nums: Int)

    //在使用时
    var dataBean: DataBean = DataBean(names, item)


}